package com.cqjtu.eecs.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cqjtu.eecs.entity.Academy;
import com.cqjtu.eecs.entity.Major;
import com.cqjtu.eecs.entity.Teacher;
import com.cqjtu.eecs.entity.User;
import com.cqjtu.eecs.entity.dto.MajorDTO;
import com.cqjtu.eecs.entity.params.major.MajorAddParams;
import com.cqjtu.eecs.entity.params.major.MajorUpdateParams;
import com.cqjtu.eecs.entity.vo.MajorVO;
import com.cqjtu.eecs.entity.vo.TeacherAcademyVO;
import com.cqjtu.eecs.entity.vo.TrainingGoalVO;
import com.cqjtu.eecs.exception.NotFoundException;
import com.cqjtu.eecs.exception.ParamsErrorException;
import com.cqjtu.eecs.service.*;
import com.cqjtu.eecs.utils.Assert;
import com.cqjtu.eecs.utils.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.sql.Wrapper;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author   luojun
 * @since 2022-02-28
 */
@RestController
@RequestMapping("/major")
@Api(tags = "专业接口")
public class MajorController {
    private final IMajorService majorService;
    private final IAcademyService academyService;
    private final ITeacherService teacherService;
    private final IUserService userService;

    public MajorController(IMajorService majorService, IAcademyService academyService, ITeacherService teacherService, IUserService userService) {
        this.majorService = majorService;
        this.academyService = academyService;
        this.teacherService = teacherService;
        this.userService = userService;
    }

    @GetMapping("/exist/{majorName}")
    @ApiOperation("判断专业是否存在")
    public Boolean judgeMajorExist(@PathVariable String majorName) {
        Major major = majorService.getOne(new QueryWrapper<Major>().eq("major_name", majorName));
        if (major != null)
            return false;
        return true;
    }

    @PostMapping("/add")
    @ApiOperation("增加一个专业")
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> addMajor(@Valid @RequestBody MajorAddParams majorAddParams){
        // 通过教师工号获取tid
        Teacher teacher = teacherService.getOne(
                new LambdaQueryWrapper<Teacher>()
                        .eq(Teacher::getTeacherCode, majorAddParams.getTeacherCode()));
        Assert.notNull(teacher, new NotFoundException("Not find the exception"));
        Major major = new Major(
                majorAddParams.getMajorCode(),
                majorAddParams.getAcademyId(),
                majorAddParams.getMajorName(),
                majorAddParams.getMajorBrief(),
                majorAddParams.getMajorManager(),
                teacher.getTid()
        );
        if (majorService.save(major) && userService.addRoleToUser(teacher.getUid(), "major_manager"))
            return Result.success();
        return Result.error();
    }

    @PutMapping("/update")
    @ApiOperation("修改专业")
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> update(@Valid @RequestBody MajorUpdateParams majorUpdateParams){
        // 通过教师工号获取tid
        Teacher teacher = teacherService.getOne(
                new LambdaQueryWrapper<Teacher>()
                        .eq(Teacher::getTeacherCode, majorUpdateParams.getTeacherCode()));
        Assert.notNull(teacher, new NotFoundException("Not find the exception"));
        Major major = new Major(
                majorUpdateParams.getMajorCode(),
                majorUpdateParams.getAcademyId(),
                majorUpdateParams.getMajorName(),
                majorUpdateParams.getMajorBrief(),
                majorUpdateParams.getMajorManager(),
                teacher.getTid()
        );
//        BeanUtils.copyProperties(majorUpdateParams, major);
        // 获取原专业信息
        Major one = majorService.getOne(new LambdaQueryWrapper<Major>()
                .eq(Major::getAcademyId, major.getAcademyId())
                .eq(Major::getMajorCode, major.getMajorCode()));
        Assert.notNull(one, new NotFoundException("Not find the major"));
        // 根据tid找到tCode
        Teacher one1 = teacherService.getOne(new LambdaQueryWrapper<Teacher>().eq(Teacher::getTid, one.getTid()));
        // 删除原系主任的角色
        userService.removeRoleByUsername(one1.getTeacherCode(), "major_manager");
        if (majorService.update(new LambdaUpdateWrapper<Major>()
                .eq(Major::getAcademyId, major.getAcademyId())
                .eq(Major::getMajorCode, major.getMajorCode())
                .set(major.getMajorName() != null, Major::getMajorName, major.getMajorName())
                .set(major.getMajorBrief() != null, Major::getMajorBrief, major.getMajorBrief())
                .set(major.getMajorManager() != null, Major::getMajorManager, major.getMajorManager())
                .set(major.getTid() != null, Major::getTid, major.getTid())
        ) &&
                userService.addRoleToUser(teacher.getUid(), "major_manager")
        ){
            return Result.success();
        }
        return Result.error();
    }
    @GetMapping("/majorByAcademyId/{id}")
    @ApiOperation("通过学院id获取学院下的全部专业")
    public List<MajorVO> getMajorListByAcademyId(@PathVariable("id")String id){
        Assert.notNull(id, new ParamsErrorException("参数异常"));
        List<MajorDTO> majorDTOList = majorService.getMajorListByAcademyId(id);
        List<MajorVO> majorVOS = new ArrayList<>();
        majorDTOList.forEach(item -> {
            MajorVO majorVO = new MajorVO();
            BeanUtils.copyProperties(item, majorVO);
            majorVOS.add(majorVO);
        });
        return majorVOS;
    }
    @GetMapping("/majorByMajorId/{id}")
    @ApiOperation("通过专业id获取专业信息")
    public MajorVO getMajorByMajorId(@PathVariable("id")String id){
        Assert.notNull(id, new ParamsErrorException("参数异常"));
        // 获取专业
        Major major = majorService.getOne(new LambdaQueryWrapper<Major>().eq(Major::getMajorCode, id));
        Assert.notNull(major, new NotFoundException("未找到该专业"));
        System.out.println(major);
        // 获取学院名
        Academy academy = academyService.getById(major.getAcademyId());
        MajorVO majorVO = new MajorVO();
        BeanUtils.copyProperties(new MajorDTO(major, academy), majorVO);
        return majorVO;
    }
    @GetMapping("/majorList")
    @ApiOperation("获取全部的专业")
    public List<MajorVO> getMajorList(){
        List<MajorDTO> majorDTOList = majorService.getMajorList();
        List<MajorVO> majorVOS = new ArrayList<>();
        majorDTOList.forEach(item -> {
            MajorVO majorVO = new MajorVO();
            BeanUtils.copyProperties(item, majorVO);
            majorVOS.add(majorVO);
        });
        return majorVOS;
    }
    @DeleteMapping("/deleteById/{id}")
    @ApiOperation("通过专业代码删除专业")
    public Result<Object> deleteById(@PathVariable("id") String id){
        Assert.notNull(id, new ParamsErrorException("id入参不能为null"));
        Assert.notBlank(id, new ParamsErrorException("id入参不能为空"));
        if (majorService.removeById(id))
            return Result.success();
        return Result.error(-1, "专业不存在");
    }
    @DeleteMapping("/deleteByName/{name}")
    @ApiOperation("通过专业名删除专业")
    public Result<Object> deleteByName(@PathVariable("name") String name){
        Assert.notNull(name, new ParamsErrorException("name入参不能为null"));
        Assert.notBlank(name, new ParamsErrorException("name入参不能为空"));
        if (majorService.remove(new LambdaQueryWrapper<Major>().eq(Major::getMajorName, name)))
            return Result.success();
        return Result.error(-1, "专业不存在");
    }

    @ApiOperation("根据学院代码获取学院下的教职工")
    @GetMapping("/listTeacher/{code}")
    public List<TeacherAcademyVO> listTeacherByAcademyCode(@PathVariable("code") String code){
        Assert.notBlank(code, new ParamsErrorException("The code can not be null or blank"));
        List<Teacher> teachers = teacherService
                .list(new LambdaQueryWrapper<Teacher>().eq(Teacher::getAcademyId, code));
        List<TeacherAcademyVO> teacherAcademyVOS = new ArrayList<>();
        teachers.forEach(item->{
            if (!userService.hasRole(item.getTeacherCode(), "major_manager"))
                teacherAcademyVOS.add(new TeacherAcademyVO(item.getTeacherCode(), item.getTeacherName()));
        });
        return teacherAcademyVOS;
    }

}
